import 'dart:convert';
import 'dart:io';

import 'package:dio/adapter.dart';
import 'package:dio/dio.dart';
import '../util/string_util.dart';
import './response/http_response.dart';

export './response/http_response.dart';
export 'http_error.dart';



class HttpManager {
  static HttpManager _instance;
  static Dio dio;

  static bool _canProxy = false;
  static String _proxyHost = "172.16.56.177:8888";
  static int _connectTimeout = 15000;
  static int _receiveTimeout = 30000;


  /// http request methods
  static const String GET = 'get';
  static const String POST = 'post';
  static const String PUT = 'put';
  static const String PATCH = 'patch';
  static const String DELETE = 'delete';

  /// 全局属性：请求前缀、连接超时时间、响应超时时间
  static BaseOptions _options = new BaseOptions(
    connectTimeout: _connectTimeout,
    receiveTimeout: _receiveTimeout,
    responseType: ResponseType.plain,
    headers: {},
  );

  static InterceptorsWrapper _interceptor;

  factory HttpManager() => _getInstance();

  static Function getHeaders = (){
    Map<String, dynamic> header = {"timestamp":DateTime.now().millisecond};
    return header;
  };

  static config({BaseOptions options,InterceptorsWrapper interceptor,bool canProxy = false, String proxyHost,int connectTimeout = 15000,int receiveTimeout = 30000}){
    if(options == null){
      _options = options;
    }
    _interceptor = interceptor;
    _canProxy = canProxy;
    _proxyHost = proxyHost;
    _connectTimeout = connectTimeout;
    _receiveTimeout = receiveTimeout;
    clear();
  }

  static HttpManager _getInstance() {
    if (_instance == null) {
      _instance = new HttpManager._();
    }
    return _instance;
  }

  HttpManager._() {
    dio = _createInstance();
  }

  /// 创建 dio 实例对象
  static Dio _createInstance() {
    //dio = null;
    if (dio == null) {
      dio = new Dio(_options);
      //请求拦截器
      if(_interceptor != null){
        dio.interceptors.clear();
        dio.interceptors.add(_interceptor);
      }
      //设置代理
      if(_canProxy && !StringUtils.isEmpty(_proxyHost)){
        (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client){
          client.badCertificateCallback = (X509Certificate cert,String host,int port){
            return Platform.isAndroid;
          };
          client.findProxy = (uri){
            if(_proxyHost == null){
              return "";
            }
            if(_proxyHost.contains("PROXY")){
              return _proxyHost;
            }
            return "PROXY $_proxyHost";
          };
        };
      }
    }
    return dio;
  }

  /// 清空 dio 对象
  static clear() {
    dio = null;
  }


  get(
      String url,
      Map<String, dynamic> headers,
      Map<String, dynamic> param,
      HttpResponse callBack,
      ) async {
    _requestHttp(
      url,
      headers: headers,
      queryParameters: param,
      method: GET,
      callBack: callBack,
    );
  }

  postForm(
      String url,
      Map<String, dynamic> headers,
      Map<String, dynamic> param,
      HttpResponse callBack,
      ) async {
    _requestHttp(
      url,
      headers: headers,
      queryParameters: param,
      method: POST,
      callBack: callBack,
    );
  }

  postFormBody(
      String url,
      Map<String, dynamic> headers,
      Map<String, dynamic> param,
      HttpResponse callBack,
      ) async {
    _requestHttp(
      url,
      headers: headers,
      data: param,
      method: POST,
      callBack: callBack,
      isFormatModel: false,
    );
  }

  postJSON(
      String url,
      Map<String, dynamic> headers,
      param,
      HttpResponse callBack,
      ) async {
    _requestHttp(
      url,
      headers: headers,
      data: param,
      method: POST,
      contentType: Headers.jsonContentType,
      callBack: callBack,
    );
  }

  static Map<String, Object> nullToEmpty(Map<String, Object> map) {
    if(map == null){
      return {};
    }
    List<String> arr = map.keys.toList();
    for(int i=0;i<arr.length;i++){
      if(map[arr[i]] == null) {
        map[arr[i]] = "" ;
      }
    }
    return map;
  }

  /// T is Map<String,dynamic>  or List<dynamic>
  static _requestHttp<T>(
      String url, {
        Map<String, dynamic> headers,
        Map<String, dynamic> queryParameters,
        data,
        String contentType = Headers.formUrlEncodedContentType,
        method,
        HttpResponse callBack,
        bool isFormatModel = true,
      }) async {
    dio = _createInstance();
    if (headers != null) {
      dio.options.headers = headers;
    }else{
      dio.options.headers = getHeaders();
    }
    dio.options.contentType = contentType;
    try {
      Response response;
      response = await dio.request(
        url,
        queryParameters: nullToEmpty(queryParameters),
        data: data,
        options: new Options(method: method),
      );
      if (response.statusCode == HttpStatus.ok) {
        if(callBack.success != null){
          try{
            if(callBack.setResponseData(response.data)){
              callBack.success(callBack.responseData());
            }else{
              HTTPError error = HTTPError(response.data, response.statusCode, callBack.serviceLogicFailMessage());
              callBack.fail(error,callBack.serviceLogicFailMessage());
            }
          }catch(e){
            HTTPError error = HTTPError(response.data, response.statusCode, "$e");
            callBack.fail(error,"$e");
            print(StackTrace.current);
            print(e);
            print(response);
          }
        }
      } else {
        if(callBack.fail != null){
          HTTPError error = HTTPError(response.data, response.statusCode, response.statusMessage);
          callBack.fail(error,response.statusMessage);
        }
      }
      if(callBack.complete != null){
        callBack.complete();
      }
    }  catch(e){
      if(callBack.fail != null){
        String msg = "【请求出错】${e.toString()}\r\n$url,headers:${jsonEncode(headers)},queryParameters:${jsonEncode(queryParameters)},data:${data},statusMessage:${e.toString()}";
        HTTPError error = HTTPError(StackTrace.current, 10000, msg);
        callBack.fail(error,e.toString());
      }
      if(callBack.complete != null){
        callBack.complete();
      }
      print(StackTrace.current);
      print(e);
    }
  }

}

/*
///日志拦截器
class LogInterceptors extends InterceptorsWrapper {
  @override
  Future onRequest(RequestOptions options) {
    Log.D("【请求url】${options.baseUrl}${options.path}");
    Log.D("【请求path】${options.path}");
    Log.D("【请求headers】${options.headers.toString()}");
    Log.D("【请求参数query】${options.queryParameters.toString()}");
    Log.D("【请求参数data】${options.data.toString()}");
    return super.onRequest(options);
  }

  @override
  Future onResponse(Response response) {
    Log.D("【返回statusCode】${response.statusCode}");
    Log.D("【返回headers】${response.headers.toString()}");
    Log.D("【返回extra】${response.extra.toString()}");
    Log.D("【返回data】${response.data.toString()}");
    return super.onResponse(response);
  }

  @override
  Future onError(DioError err) {
    Log.Er(err.toString());
    Log.Er(err.response?.toString());
    return super.onError(err);
  }
}*/